package com.jungle.client;

import com.google.gson.reflect.TypeToken;
import com.jungle.bfi.domain.vo.DataDefinitionVo;
import com.jungle.bfi.domain.vo.DatasetItemVo;
import com.jungle.bfi.domain.vo.Option;
import com.jungle.client.channel.HttpClient;
import com.jungle.client.vo.ScenarioFactorVo;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import lombok.extern.slf4j.Slf4j;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

@Slf4j
public class BizScenarioController implements Initializable {
    @FXML
    private GridPane gridPane;

    public void initialize(URL location, ResourceBundle resources) {
        log.info("init BizScenarioController, location:{}", location);
    }

    public void refreshComponent(DataDefinitionVo dataDefinitionVo) {
        log.info("refresh BizScenarioController");
        if (dataDefinitionVo == null) {
            return;
        }
        DataDefinitionVo vo = new DataDefinitionVo();
        vo.setApiId(dataDefinitionVo.getApiId());
        vo.setApiPath(dataDefinitionVo.getApiPath());
        vo.setScenarioFlag(true);
        HttpClient.getInstance().post("/dataDefinition/list", vo).callback(new TypeToken<List<DataDefinitionVo>>() {
        }, list -> {
            if (list != null && !list.isEmpty()) {
                AtomicInteger rowIndex = new AtomicInteger(0);
                for (DataDefinitionVo definitionVo : list) {
                    layoutComponent(rowIndex, definitionVo);
                }

                // TODO 加载数据

                Button button = new Button("应用");
                button.setOnAction(event -> readData());
                gridPane.add(button, 0, list.size() + 1);
            }
        });
    }

    private void layoutComponent(AtomicInteger rowIndex, DataDefinitionVo vo) {
        String datasetId = vo.getDatasetId();
        if (datasetId != null) {
            DatasetItemVo datasetItemVo = new DatasetItemVo();
            datasetItemVo.setDatasetId(datasetId);
            // 获取数据字典
            HttpClient.getInstance().post("/datasetItem/list", datasetItemVo).callback(new TypeToken<List<DatasetItemVo>>() {
            }, list -> {
                List<Option> options = Optional.ofNullable(list).orElse(new ArrayList<>(0)).stream().map(item -> new Option(item.getDisplayValue(), item.getValue())).toList();
                if (options.size() > 1) {
                    layoutComboBox(rowIndex.incrementAndGet(), vo, options);
                }
            });
        }
    }

    private void layoutComboBox(int rowIndex, DataDefinitionVo vo, List<Option> options) {
        // 构建 标题
        gridPane.add(new Label(vo.getTitle()), 0, rowIndex);
        // 构建 下拉框
        ComboBox<Option> comboBox = buildComboBox(options);
        // 设置下拉框id
        comboBox.setId(vo.getDatasetId());
        // 添加到gridPane
        gridPane.add(comboBox, 1, rowIndex);
    }

    private ComboBox<Option> buildComboBox(List<Option> options) {
        return new ComboBox<>(FXCollections.observableArrayList(options));
    }

    public void loadData(List<ScenarioFactorVo> list) {
        forEach(comboBox -> {
            String comboBoxId = comboBox.getId();
            list.stream().filter(vo -> comboBoxId.equals(vo.getDatasetId())).findAny().ifPresent(vo ->
                    comboBox.setValue(null)
            );
        });
    }

    private void readData() {
        forEach(comboBox ->
                log.info("comboBoxId:{}, value:{} ", comboBox.getId(), comboBox.getValue())
        );
    }

    public void resetData() {
        forEach(comboBox -> comboBox.setValue(null));
    }

    private void forEach(Consumer<ComboBox<?>> consumer) {
        gridPane.getChildren().stream().filter(ComboBox.class::isInstance).forEach(node -> {
            ComboBox<?> comboBox = (ComboBox<?>) node;
            String comboBoxId = comboBox.getId();
            if (comboBoxId != null) {
                consumer.accept(comboBox);
            }
        });
    }
}
